/**
 * 
 */
package jvs.vfs.opt.contact;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import jvs.vfs.opt.contact.eclair.ContactsContract;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

/**
 * @author qiangli
 * 
 */
public class ContactAdapter2 extends ContactAdapter {

	private static final String LOG_TAG = "ContactAdapter2";

	public ContactAdapter2() {
	}

	@Override
	protected void loadContactsInContact(Context ctx, Set<ContactInfo> contacts) {
		String sel = ContactsContract.Data.MIMETYPE + " in (? , ?)";
		loadEmailContact(ctx, sel, contacts);
	}

	@Override
	protected void loadFavoriteInContact(Context ctx, Set<ContactInfo> contacts) {
		String sel = ContactsContract.Contacts.STARRED + " != 0 AND "
				+ ContactsContract.Data.MIMETYPE + " in (? , ?)";
		loadEmailContact(ctx, sel, contacts);
	}

	private void loadEmailContact(Context ctx, String sel,
			Set<ContactInfo> contacts) {
		Uri uri = ContactsContract.Data.CONTENT_URI;
		String[] proj = new String[] { ContactsContract.Data.RAW_CONTACT_ID,
				ContactsContract.Contacts.CONTACT_ID,
				ContactsContract.Contacts.DISPLAY_NAME,
				ContactsContract.Contacts.STARRED,
				ContactsContract.Contacts.LAST_TIME_CONTACTED,
				ContactsContract.Contacts.TIMES_CONTACTED,
				ContactsContract.Data.MIMETYPE,
				ContactsContract.CommonDataKinds.Email.ADDRESS };
		String by = ContactsContract.Contacts.DISPLAY_NAME + " ASC ";

		String[] args = new String[] {
				ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE,
				ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE };
		ContentResolver cr = ctx.getContentResolver();
		Cursor c = cr.query(uri, proj, sel, args, by);
		if (c == null) {
			return;
		}
		try {
			if (!c.moveToFirst()) {
				return;
			}
			//
			int colCid = c.getColumnIndex(ContactsContract.Contacts.CONTACT_ID);
			int colId = c.getColumnIndex(ContactsContract.Data.RAW_CONTACT_ID);
			int colName = c
					.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
			int colStar = c.getColumnIndex(ContactsContract.Contacts.STARRED);
			int colLastTime = c
					.getColumnIndex(ContactsContract.Contacts.LAST_TIME_CONTACTED);
			int colTimes = c
					.getColumnIndex(ContactsContract.Contacts.TIMES_CONTACTED);
			int colEmail = c
					.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS);
			//
			String prev = "";
			ContactInfo ec = null;
			ArrayList<String> el = new ArrayList<String>(); // emails
			do {
				String n = c.getString(colName);
				if (n.equals(prev)) {
					String s = c.getString(colEmail);
					//
					if (!el.contains(s)) {
						el.add(s);
					}
					//
					ec.lastTime = Math.max(ec.lastTime, c.getLong(colLastTime));
					ec.times += c.getInt(colTimes);
				} else {
					// new entry
					if (ec != null) {
						ec.emails = el.toArray(new String[0]);
						contacts.add(ec);
					}
					//
					ec = new ContactInfo();
					el.clear();
					prev = n;
					//
					ec.cid = c.getLong(colCid);
					ec.id = c.getString(colId);
					ec.name = n;
					//
					ec.starred = c.getInt(colStar);
					ec.lastTime = c.getLong(colLastTime);
					ec.times = c.getInt(colTimes);
					//
					ec.sortkey = n;
					//
					String s = c.getString(colEmail);
					el.add(s);
					//
				}
			} while (c.moveToNext());

			if (ec != null) {
				ec.emails = el.toArray(new String[0]);
				contacts.add(ec);
			}
		} finally {
			c.close();
		}
	}

	@Override
	protected boolean hasEmailInContact(Context context, String email) {
		Uri uri = ContactsContract.Data.CONTENT_URI;
		String[] proj = new String[] { ContactsContract.CommonDataKinds.Email.ADDRESS };
		String sel = ContactsContract.CommonDataKinds.Email.ADDRESS + "= ?";
		String[] args = new String[] { email };
		ContentResolver cr = context.getContentResolver();
		Cursor c = cr.query(uri, proj, sel, args, null);
		if (c == null) {
			return false;
		}
		try {
			boolean has = (c.moveToFirst());
			//
			return has;
		} finally {
			c.close();
		}
	}

	@Override
	protected long getContactId(Context ctx, String name) {
		Uri uri = ContactsContract.Data.CONTENT_URI;
		String[] proj = new String[] { ContactsContract.Data.RAW_CONTACT_ID,
				ContactsContract.Contacts.DISPLAY_NAME };
		Cursor c = ctx.getContentResolver().query(uri, proj,
				ContactsContract.Contacts.DISPLAY_NAME + " = ?",
				new String[] { name }, null);
		if (c == null) {
			return -1;
		}
		try {
			if (!c.moveToFirst()) {
				return -1;
			}
			// return the first one found
			int idCol = c.getColumnIndex(ContactsContract.Data.RAW_CONTACT_ID);
			long id = c.getLong(idCol);
			//
			return id;
		} finally {
			c.close();
		}
	}

	@Override
	protected String[] getEmailsInContact(Context ctx, String name) {
		Uri uri = ContactsContract.Data.CONTENT_URI;
		String[] proj = new String[] { ContactsContract.Contacts.DISPLAY_NAME,
				ContactsContract.CommonDataKinds.Email.ADDRESS };
		String sel = ContactsContract.Contacts.DISPLAY_NAME + " = ? AND "
				+ ContactsContract.Data.MIMETYPE + " in (? , ?)";
		String[] args = new String[] { name,
				ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE,
				ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE };
		ContentResolver cr = ctx.getContentResolver();
		Cursor c = cr.query(uri, proj, sel, args, null);
		if (c == null) {
			return null;
		}
		try {
			if (!c.moveToFirst()) {
				return null;
			}
			Set<String> set = new HashSet<String>();
			int col = c
					.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS);
			while (c.moveToNext()) {
				String email = c.getString(col);
				set.add(email);
			}
			return set.toArray(new String[0]);
		} finally {
			c.close();
		}
	}

	@Override
	protected void loadGroupNamesInConact(Context ctx, Set<String> names) {
		Uri uri = ContactsContract.Data.CONTENT_URI;
		String[] proj = new String[] { ContactsContract.Contacts.DISPLAY_NAME,
				ContactsContract.CommonDataKinds.Email.ADDRESS };
		String sel = ContactsContract.Contacts.DISPLAY_NAME + " like ? AND "
				+ ContactsContract.Data.MIMETYPE + " in (? , ?)";
		String[] args = new String[] { "@%",
				ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE,
				ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE };
		ContentResolver cr = ctx.getContentResolver();
		Cursor c = cr.query(uri, proj, sel, args, null);
		if (c == null) {
			return;
		}
		try {
			if (!c.moveToFirst()) {
				return;
			}
			int colName = c
					.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
			int colEmail = c
					.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS);
			do {
				String a = c.getString(colEmail);
				if (TextUtils.isEmpty(a)) {
					continue;
				}
				String n = c.getString(colName);
				names.add(n);
			} while (c.moveToNext());
		} finally {
			c.close();
		}
	}

	@Override
	public void loadPhoneContacts(Context ctx, List<ContactInfo> contacts,
			int idx, String by) {
		String sel = ContactsContract.Data.MIMETYPE + " = ? ";
		loadPhoneContacts(ctx, sel, contacts, idx, by);
	}

	private void loadPhoneContacts(Context ctx, String sel,
			List<ContactInfo> contacts, int idx, String sortby) {
		Uri uri = ContactsContract.Data.CONTENT_URI;
		String[] proj = new String[] { ContactsContract.Contacts._ID,
				ContactsContract.Data.RAW_CONTACT_ID,
				ContactsContract.Contacts.CONTACT_ID,
				ContactsContract.Contacts.DISPLAY_NAME,
				ContactsContract.Contacts.STARRED,
				ContactsContract.Contacts.LAST_TIME_CONTACTED,
				ContactsContract.Contacts.TIMES_CONTACTED,
				ContactsContract.Data.MIMETYPE,
				ContactsContract.CommonDataKinds.Organization.PHONETIC_NAME,
				ContactsContract.CommonDataKinds.Phone.NUMBER,
				ContactsContract.CommonDataKinds.Phone.LABEL,
				ContactsContract.CommonDataKinds.Phone.TYPE };
		//
		
		String[] args = new String[] { ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE };
		ContentResolver cr = ctx.getContentResolver();

		Cursor c = cr.query(uri, proj, sel, args, sortby);
		if (c == null) {
			return;
		}
		try {
			if (DEBUG) {
				Log.d(LOG_TAG, "loadPhoneContacts count: " + c.getCount()
						+ " sort: " + sortby);
			}
			if (!c.moveToFirst()) {
				return;
			}
			//
			int colId = c.getColumnIndex(ContactsContract.Data._ID);
			int colCid = c.getColumnIndex(ContactsContract.Contacts.CONTACT_ID);
			// int colRid =
			// c.getColumnIndex(ContactsContract.Data.RAW_CONTACT_ID);
			int colName = c
					.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
			int colPName = c
					.getColumnIndex(ContactsContract.CommonDataKinds.Organization.PHONETIC_NAME);
			int colStar = c.getColumnIndex(ContactsContract.Contacts.STARRED);
			int colLastTime = c
					.getColumnIndex(ContactsContract.Contacts.LAST_TIME_CONTACTED);
			int colTimes = c
					.getColumnIndex(ContactsContract.Contacts.TIMES_CONTACTED);
			int colNumber = c
					.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
			int colType = c
					.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE);
			int colLabel = c
					.getColumnIndex(ContactsContract.CommonDataKinds.Phone.LABEL);
			//
			long sortkey = System.currentTimeMillis();
			do {
				ContactInfo ec = new ContactInfo();
				String num = c.getString(colNumber);
				if (TextUtils.isEmpty(num)) {
					continue;
				}
				ec.index = idx;
				ec.phone = num;
				ec.id = c.getString(colId);
				ec.cid = c.getLong(colCid);
				ec.name = c.getString(colName);
				ec.phoneticName = c.getString(colPName);
				ec.starred = c.getInt(colStar);
				ec.lastTime = c.getLong(colLastTime);
				ec.times = c.getInt(colTimes);
				int type = c.getInt(colType);
				int pType = ContactInfo.TYPE_OTHER;
				switch (type) {
				case ContactsContract.CommonDataKinds.Phone.TYPE_HOME:
					pType = ContactInfo.TYPE_HOME;
					break;
				case ContactsContract.CommonDataKinds.Phone.TYPE_WORK:
					pType = ContactInfo.TYPE_WORK;
					break;
				case ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE:
					pType = ContactInfo.TYPE_MOBILE;
					break;
				case ContactsContract.CommonDataKinds.Phone.TYPE_CUSTOM:
					pType = ContactInfo.TYPE_CUSTOM;
					break;
				case ContactsContract.CommonDataKinds.Phone.TYPE_OTHER:
					pType = ContactInfo.TYPE_OTHER;
					break;
				}
				ec.phoneType = pType;
				ec.phoneLabel = c.getString(colLabel);

				sortkey++;
				ec.sortkey = "" + sortkey;
				//
				contacts.add(ec);
				//
				if (DEBUG) {
					Log.d(LOG_TAG, "loadPhoneContacts added. sortkey: "
							+ sortkey + " " + ec);
				}
			} while (c.moveToNext());
		} finally {
			c.close();
		}
	}

	@Override
	public void loadPhoneFavorite(Context ctx, List<ContactInfo> contacts,
			int idx, String by) {
		String sel = ContactsContract.Contacts.STARRED +" != 0 AND " + ContactsContract.Data.MIMETYPE + " = ?";
		loadPhoneContacts(ctx, sel, contacts, idx, by);
	}
}
